package com.xw.bo.ks.util;

import cn.hutool.core.date.DateUtil;
import com.xw.bo.ks.entity.base.DayCompareBean;
import com.xw.bo.ks.entity.base.QueryTime;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

@Slf4j
public class TimeQueueUtil {

    /**
     * 给定的时间范围内，按小时存入队列中
     *
     * @param startTime 开始时间时间戳，单位是毫秒
     * @param endTime   结束时间时间戳，单位是毫秒
     * @return 除了结尾，每个元素的差额是一小时
     */
    public static ArrayBlockingQueue<QueryTime> getHourTime(long startTime, long endTime) {
        if (startTime > endTime) {
            return new ArrayBlockingQueue<QueryTime>(0);
        }

        long differenceTime = endTime - startTime;
        int hours = (int) (differenceTime / 3600000) + 2;

        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(hours);

        long flagTime = startTime;
        for (int i = 0; i < hours; i++) {
            QueryTime queryTime = new QueryTime();
            queryTime.setStartTime(flagTime);
            long endQueueTime = flagTime + 3599999;
            if (endQueueTime >= endTime) {
                queryTime.setEndTime(endTime);
                blockingQueue.add(queryTime);
                break;
            }
            queryTime.setEndTime(endQueueTime);
            flagTime = endQueueTime + 1;
            blockingQueue.add(queryTime);
        }

        return blockingQueue;

    }

    /**
     * 见同名方法注释
     *
     * @param startTime 开始时间 开始时间时间戳，单位是毫秒
     * @return 按天计算, 从前往后的队列时间
     */
    public static ArrayBlockingQueue<QueryTime> getDayTime(long startTime) {
        long currentTime = System.currentTimeMillis();
        return getDayTime(startTime, currentTime);
    }

    /**
     * 从起始时间开始算起，到今天，除了最开始和最后时间,
     * 每个元素都是每天的0点0分0秒，结束时间是23：59：59
     *
     * @param startTime 开始时间 开始时间时间戳，单位是毫秒
     * @param overTime  结束时间 时间戳 单位是毫秒
     * @return 按天计算, 从前往后的队列时间
     */
    public static ArrayBlockingQueue<QueryTime> getDayTime(long startTime, long overTime) {

        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(1);
        if (0 == overTime) {
            return blockingQueue;
        }

        if (startTime > overTime) {
            return blockingQueue;
        }

        // 一般currentTime就是指定范围的结束时间
        long currentTime = overTime;

        int days = (int) ((currentTime - startTime) / 86400000) + 2;

        blockingQueue = new ArrayBlockingQueue<>(days);
        long queryStartTime = startTime;
        while (queryStartTime <= currentTime) {
            QueryTime queryTime = new QueryTime();
            queryTime.setStartTime(queryStartTime);

            long endTime = DateUtils.getDayEnd(new Date(queryStartTime)).getTime();
            if (endTime > currentTime) {
                queryTime.setEndTime(currentTime);
            } else {
                queryTime.setEndTime(endTime);
            }
            blockingQueue.add(queryTime);

            queryStartTime += 86400000;
            queryStartTime = DateUtils.getDayStart(new Date(queryStartTime)).getTime();
        }

        return blockingQueue;
    }

    public static List<Long> getTimeByDayList(long startTime, long overTime) {
        List<Long> dayTime = new ArrayList<>();

        if (0 == overTime) {
            return dayTime;
        }

        if (startTime > overTime) {
            return dayTime;
        }

        // 一般currentTime就是指定范围的结束时间
        long currentTime = overTime;

        long queryStartTime = startTime;
        while (queryStartTime <= currentTime) {

            if (queryStartTime + 86400000 > currentTime) {
                dayTime.add(currentTime);
                break;
            } else {
                dayTime.add(queryStartTime);
            }
            queryStartTime += 86400000;
        }
        return dayTime;
    }


    /**
     * 见getMonthTime同名方法的注释
     *
     * @param startTime 开始时间
     * @return 月份起始队列时间
     */
    public static ArrayBlockingQueue<QueryTime> getMonthTime(long startTime) {
        return getMonthTime(startTime, System.currentTimeMillis());
    }

    /**
     * 从起始时间开始算起，到今天，除了最开始和最后时间,
     * 每个元素都是每月1号的0点0分0秒，结束时间是月底那一天的23：59：59
     *
     * @param startTime 开始时间
     * @param overTime  结束时间
     * @return 月份起始队列时间
     */
    public static ArrayBlockingQueue<QueryTime> getMonthTime(long startTime, long overTime) {
        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(1);
        if (0 == overTime) {
            return blockingQueue;
        }

        if (startTime > overTime) {
            return blockingQueue;
        }

        // 一般currentTime就是指定范围的结束时间
        long currentTime = overTime;
        DayCompareBean dayCompare = DateUtils.dayCompare(startTime, overTime);
        Date startDate = new Date(startTime);

        blockingQueue = new ArrayBlockingQueue<>(dayCompare.getMonth() + 1);
        long queryStartTime = startTime;
        while (queryStartTime <= currentTime) {
            QueryTime queryTime = new QueryTime();
            queryTime.setStartTime(queryStartTime);

            long endTime = DateUtil.endOfMonth(startDate).getTime();

            if (endTime > currentTime) {
                queryTime.setEndTime(currentTime);
            } else {
                queryTime.setEndTime(endTime);
            }
            blockingQueue.add(queryTime);

            Date nextMonth = DateUtils.getMonth(startDate, 1);
            startDate = DateUtil.beginOfMonth(nextMonth);
            queryStartTime = startDate.getTime();
        }

        return blockingQueue;
    }

    /**
     * 获取队列，开始时间到结束时间，队列中只有一个元素
     *
     * @param startTime 开始时间
     * @param days      天数
     * @return 队列 从开始时间到 开始时间之后的天数时间
     */
    public static ArrayBlockingQueue<QueryTime> getOneTimeQueue(long startTime, int days) {
        long endTime = startTime + (86400000 * days);

        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(1);
        QueryTime queryTime = new QueryTime();
        queryTime.setStartTime(startTime);
        queryTime.setEndTime(endTime);

        blockingQueue.add(queryTime);

        return blockingQueue;
    }

    /**
     * 获取队列，开始时间是结束时间减掉天数对应时间
     *
     * @param endTime 结束时间
     * @param days    天使
     * @return
     */
    public static ArrayBlockingQueue<QueryTime> getBeforeDayTime(long endTime, int days) {
        long startTime = endTime - (86400000 * days);

        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(1);
        QueryTime queryTime = new QueryTime();
        queryTime.setStartTime(startTime);
        queryTime.setEndTime(endTime);

        blockingQueue.add(queryTime);

        return blockingQueue;
    }


    /**
     * 从起始时间开始算起，到今天，除了最开始和最后时间,
     * 每个元素都是分钟计算，每3分钟一个计时
     *
     * @param startTime 开始时间 开始时间时间戳，单位是毫秒
     * @param endTime  结束时间 时间戳 单位是毫秒
     * @return 按3分钟计算, 从前往后的队列时间
     */
    public static ArrayBlockingQueue<QueryTime> getMinTime(long startTime, long endTime) {
        if (startTime > endTime) {
            return new ArrayBlockingQueue<QueryTime>(0);
        }

        long differenceTime = endTime - startTime;
        int hours = (int) (differenceTime / 180000) + 2;

        ArrayBlockingQueue<QueryTime> blockingQueue = new ArrayBlockingQueue<>(hours);

        long flagTime = startTime;
        for (int i = 0; i < hours; i++) {
            QueryTime queryTime = new QueryTime();
            queryTime.setStartTime(flagTime);
            long endQueueTime = flagTime + 179999;
            if (endQueueTime >= endTime) {
                queryTime.setEndTime(endTime);
                blockingQueue.add(queryTime);
                break;
            }
            queryTime.setEndTime(endQueueTime);
            flagTime = endQueueTime + 1;
            blockingQueue.add(queryTime);
        }

        return blockingQueue;
    }



    public static void main(String[] args) {

//        String dateByNumber = DateUtils.formatDateByNumber(1692554460000L, DateUtils.DATE_PATTERN_TABLE);
//
//        log.info("dateByNumber = {}", dateByNumber);


//        ArrayBlockingQueue<QueryTime> dayTime = TimeQueueUtil.getMonthTime(1698076800000L, 1724176860000L);

        long startTime = DateUtil.beginOfDay(new Date(System.currentTimeMillis())).getTime();
        long endTime = DateUtil.endOfDay(new Date(System.currentTimeMillis())).getTime();
        String start = DateUtils.formatDateByNumber(startTime, DateUtils.DATE_PATTERN_DEFAULT);
        String end = DateUtils.formatDateByNumber(endTime, DateUtils.DATE_PATTERN_DEFAULT);
        log.info("startTime = {}", start);
        log.info("startTime = {}", end);

//        List<Long> dayTime = TimeQueueUtil.getTimeByDayList(startTime, endTime);

        ArrayBlockingQueue<QueryTime> dayTime = getMinTime(startTime,endTime);
        log.info("size = {}", dayTime.size());
//        for (Long time : dayTime) {
//            String dateByNumberStart = DateUtils.formatDateByNumber(time, DateUtils.DATE_PATTERN_DEFAULT);
//            log.info("startTime = {}", dateByNumberStart);
//        }
        while (!dayTime.isEmpty()) {
            QueryTime poll = dayTime.poll();
            String dateByNumberStart = DateUtils.formatDateByNumber(poll.getStartTime(), DateUtils.DATE_PATTERN_DEFAULT);
            String dateByNumberEnd = DateUtils.formatDateByNumber(poll.getEndTime(), DateUtils.DATE_PATTERN_DEFAULT);

            log.info("startTime = {},endTime = {}", dateByNumberStart, dateByNumberEnd);
        }
    }


}
